/**
 * 生产者-消费者与队列
 *
 * @author fireway
 * @since 2019年 02月 24日 星期日 09:25:42 CST
 */
package concurrency;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;

class LiftOffRunner implements Runnable {
    private BlockingQueue<LiftOff> mRockets;

    public LiftOffRunner(BlockingQueue<LiftOff> queue) {
        mRockets = queue;
    }

    public void add(LiftOff liftOff) {
        try {
            System.out.println("LiftOffRunner.add " + liftOff + " in " + Thread.currentThread());
            mRockets.put(liftOff);
        } catch (InterruptedException e) {
            System.out.println("Interrupted during put()");
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            while(!Thread.interrupted()) {
                LiftOff rocket = mRockets.take();
                System.out.println("take " + rocket + " in " + Thread.currentThread());
                rocket.run();
            }
        } catch(InterruptedException e) {
            System.out.println("Waking from take()");
        }
        System.out.println("Exiting LiftOffRunner");
    }
}

public class TestBlockingQueues {
    private static void getkey() {
        try {
            new BufferedReader(new InputStreamReader(System.in)).readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void getkey(String message) {
        System.out.println(message);
        getkey();
    }

    private static void test(String msg, BlockingQueue<LiftOff> queue) {
        System.out.println(msg);
        LiftOffRunner runner = new LiftOffRunner(queue);
        Thread t = new Thread(runner);
        t.start();
        for(int i = 0; i < 5; i++) {
            runner.add(new LiftOff(4));
        }
        getkey("Press 'Enter' (" + msg + ")");

        t.interrupt();
        System.out.println("Finished " + msg + " test");
    }

    public static void main(String[] args) {
//        // Unlimited size
//        test("LinkedBlockingQueue", new LinkedBlockingQueue<LiftOff>());

        // Fixed size
        test("ArrayBlockingQueue", new ArrayBlockingQueue<LiftOff>(3));
//
//        // Size of 1
//        test("SynchronousQueue", new SynchronousQueue<LiftOff>());
    }
}
